home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: thinkage.on.ca!atbowler
- From: atbowler@thinkage.on.ca (Alan Bowler)
- Subject: Re: Pre-processing: Can this be done?
- Message-ID: <Dn3n9K.LCu@thinkage.on.ca>
- Sender: news@thinkage.on.ca
- Organization: Thinkage Ltd.
- References: <DMGo4t.7r7@gti-ia.nl> <4fe164$nmg@news.cencom.net>
- Date: Wed, 21 Feb 1996 00:12:55 GMT
-
- In article <4fe164$nmg@news.cencom.net> tanp@ns (Bill Wendling) writes:
- >Paul Wallis inexplicably wrote:
- >} Hi all,
- >
- >} I'm trying to write a function which will print trace statements.
- >} I want the file and line to be added to the argument list
- >} automatically. I am, however, having some problems working
- >} my way around the pre-processor. I would like to be able to enter
- >} the following line:
- >
- >} trace("%d, %f", an_int, a_float);
- >
- >} and have the arguments passed as so:
- >
- >} _trace(__FILE__, __LINE__, "%d, %f", an_int, a_float);
- >
- >} I have defined a macro trace so:
- >
- >} #define trace(x) _trace(__FILE__, __LINE__, x)
- >
- >Try
- >
- >#define trace(x, y, z) _trace(__FILE__, __LINE__, x, y, z)
- >
- >You have 3 parms, not one.
- >
- I think that he wants to pass a variable number of arguments.
- You can't define such macro with standard C although some compilers
- do allow an extension.
-
- You can however get someting *almost* as good with a standard
- preprocessor.
-
- The first cut at doing this is something like the following:
-
- #define trace mytrace(__FILE__, __LINE, /* Note the unpaired ( */
-
- later on to use it you could code
-
- trace "%d, %f", an_int, a_float); /* close the function here */
-
- This is ugly because of the unpaired () in the source, but more so
- because you can't easily remove the trace by changing the macro.
-
- The second cut splits the trace into two calls.
-
- extern void tracehead(const char *srcfile, int srcline);
- extern void traceinfo(const char *fmt, ...);
-
- #define trace(args) { \
- tracehead(__FILE__, __LINE); \
- traceinfo args ; /* Note no () */ \
- }
-
- Later to use the trace call, you code
-
- trace(( "%d, %f", an_int, a_float));
-
- The double (( and )) is only mildly ugly, but serves to reduce the
- full list to a single macro argument. You can then define away
- the trace calls with
-
- #define trace(args) /* Nothing */
-
- If you really don't like the (( )) solution you can define a
- series of macros. trace1(fmt) trace2(fmt,a1), trace3(fmt,a1,a2) ...
-